package com.yyfax.pay.depository.service.inner.impl;

import javax.annotation.Resource;

import com.yyfax.commons.json.JacksonUtil;
import com.yyfax.pay.common.enums.*;
import com.yyfax.pay.common.exception.PayException;
import com.yyfax.pay.console.domain.ExceptionRecordDO;
import com.yyfax.pay.console.service.ExceptionRecordService;
import com.yyfax.pay.console.service.impl.EntrustChargeExpHandler;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.yyfax.commons.json.FastJsonUtil;
import com.yyfax.commons.lang.DateUtil;
import com.yyfax.framework.common.Log;
import com.yyfax.pay.common.exception.PayExceptionCode;
import com.yyfax.pay.common.model.to.YYPayApiReq2;
import com.yyfax.pay.common.model.vo.PayRspCodeVO;
import com.yyfax.pay.common.model.vo.RspParamsVO;
import com.yyfax.pay.common.util.FuiouIdUtils;
import com.yyfax.pay.depository.dao.FuiouChargeDao;
import com.yyfax.pay.depository.dao.FuiouFrozenAppropriateDao;
import com.yyfax.pay.depository.dao.FuiouFrozenDao;
import com.yyfax.pay.depository.dao.FuiouFrozenToFrozenDao;
import com.yyfax.pay.depository.dao.FuiouFrozenTransferDao;
import com.yyfax.pay.depository.dao.FuiouTransferMerchantUserDao;
import com.yyfax.pay.depository.dao.FuiouTransferUserUserDao;
import com.yyfax.pay.depository.dao.FuiouUnfrozenDao;
import com.yyfax.pay.depository.dao.FuiouWithdrawDao;
import com.yyfax.pay.depository.domain.FuiouCharge;
import com.yyfax.pay.depository.domain.FuiouWithdraw;
import com.yyfax.pay.depository.service.inner.FuiouDepositCommonService;
import com.yyfax.pay.depository.service.inner.TradeNotifyService;
import com.yyfax.pay.order.model.vo.PayBusiIdVO;
import com.yyfax.pay.order.service.PayCommonService;
import com.yyfax.pay.third.facade.fuioudeposit.FuiouDepositService;
import com.yyfax.pay.third.facade.fuioudeposit.FuiouSignService;
import com.yyfax.pay.third.model.to.fuioudeposit.BasePlainXMLRsp;
import com.yyfax.pay.third.model.to.fuioudeposit.EntrustTradeNotifyReq;
import com.yyfax.pay.third.model.to.fuioudeposit.ResultXMLRsp;
import com.yyfax.pay.third.model.to.fuioudeposit.TradeNotifyReq;
import com.yyfax.pay.third.model.to.fuioudeposit.WithdrawNotifyReq;

/**
 * 交易通知实现
 *
 * @author heizq
 * @date 2017-09-07 10:21:42
 * @since v1.0.0
 */
@Service
public class TradeNotifyServiceImpl implements TradeNotifyService {

	Logger logger = LoggerFactory.getLogger(getClass());

	@Resource
	private FuiouIdUtils fuiouIdUtils;

	@Resource
	private FuiouFrozenDao fuiouFrozenDao;

	@Resource
	private FuiouFrozenTransferDao fuiouFrozenTransferDao;

	@Resource
	private FuiouFrozenAppropriateDao fuiouFrozenAppropriateDao;

	@Resource
	private FuiouFrozenToFrozenDao fuiouFrozenToFrozenDao;

	@Resource
	private FuiouUnfrozenDao fuiouUnfrozenDao;

	@Resource
	private FuiouTransferMerchantUserDao transferMerchantUserDao;
	@Resource
	private FuiouTransferUserUserDao transferUserUserDao;
	@Resource
	private FuiouWithdrawDao fuiouWithdrawDao;
	@Resource
	private FuiouSignService fuiouSignService;
	@Resource
	private FuiouDepositCommonService fuiouDepositCommonService;
	@Resource
	private FuiouDepositService fuiouDepositService;
	@Resource
	private PayCommonService payCommonService;
	@Resource
	private FuiouChargeDao fuiouChargeDao;
	@Resource
	private EntrustChargeExpHandler entrustChargeExpHandler;

	@Resource
	private ExceptionRecordService exceptionRecordService;

	@Override
	public String tradeNotify(TradeNotifyReq req) {
		final String op = "TradeNotifyServiceImpl.tradeNotify";
		logger.info(Log.op(op).kv("param", req).msg("请求参数！").toString());

		if (null == req || StringUtils.isBlank(req.getMchnt_txn_ssn())) {
			logger.warn(Log.op(op).msg("【富友存管】通知参数异常,直接返回").kv("req", req).toString());
			return "";
		}

		// 1.解析业务订单id
		PayBusiIdVO idVO = fuiouIdUtils.parserBusiId(req.getMchnt_txn_ssn());

		boolean flag = fuiouDepositService.checkSignRspResult(idVO.getMerchantCode(), req, req.getSignature());
		if (!flag) {
			throw PayExceptionCode.ERROR_SIGN_FAIL.exp();
		}

		FuiouBusiTypeEnum busiType = idVO.getBusiType();
		PayRspCodeVO codeExp = fuiouDepositService.converToPayRspCode(req.getResp_code());
		int updateItem = 0;
		switch (busiType) {
		// 冻结
		case FROZEN:
			if (!FuiouDepositRspCodeEnum.SUCCESS.getValue().equals(req.getResp_code())) {
				updateItem = fuiouFrozenDao.updateStateByBusiId(FuiouDepositStateEnum.FAIL.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), codeExp.getCode(), codeExp.getDesc());
			} else {
				updateItem = fuiouFrozenDao.updateStateByBusiId(FuiouDepositStateEnum.SUCCESS.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), PayExceptionCode.SUCCESS.getCode(), PayExceptionCode.SUCCESS.getDesc());
			}
			break;
		// 转账预冻结
		case TRANSFER_FROZEN:
			if (!FuiouDepositRspCodeEnum.SUCCESS.getValue().equals(req.getResp_code())) {
				updateItem = fuiouFrozenTransferDao.updateStateByBusiId(FuiouDepositStateEnum.FAIL.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), codeExp.getCode(), codeExp.getDesc());
			} else {
				updateItem = fuiouFrozenTransferDao.updateStateByBusiId(FuiouDepositStateEnum.SUCCESS.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), PayExceptionCode.SUCCESS.getCode(), PayExceptionCode.SUCCESS.getDesc());
			}
			break;
		// 划拨预冻结
		case APPROPRIATE_FROZEN:
			if (!FuiouDepositRspCodeEnum.SUCCESS.getValue().equals(req.getResp_code())) {
				updateItem = fuiouFrozenAppropriateDao.updateStateByBusiId(FuiouDepositStateEnum.FAIL.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), codeExp.getCode(), codeExp.getDesc());
			} else {
				updateItem = fuiouFrozenAppropriateDao.updateStateByBusiId(FuiouDepositStateEnum.SUCCESS.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), PayExceptionCode.SUCCESS.getCode(), PayExceptionCode.SUCCESS.getDesc());
			}
			break;
		// 冻结到冻结
		case FROZEN_TO_FRONZEN:
			if (!FuiouDepositRspCodeEnum.SUCCESS.getValue().equals(req.getResp_code())) {
				updateItem = fuiouFrozenToFrozenDao.updateStateByBusiId(FuiouDepositStateEnum.FAIL.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), codeExp.getCode(), codeExp.getDesc());
			} else {
				updateItem = fuiouFrozenToFrozenDao.updateStateByBusiId(FuiouDepositStateEnum.SUCCESS.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), PayExceptionCode.SUCCESS.getCode(), PayExceptionCode.SUCCESS.getDesc());
			}
			break;
		// 解冻
		case UNFROZEN:
			if (!FuiouDepositRspCodeEnum.SUCCESS.getValue().equals(req.getResp_code())) {
				updateItem = fuiouUnfrozenDao.updateStateByBusiId(FuiouDepositStateEnum.FAIL.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), codeExp.getCode(), codeExp.getDesc());
			} else {
				updateItem = fuiouUnfrozenDao.updateStateByBusiId(FuiouDepositStateEnum.SUCCESS.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), PayExceptionCode.SUCCESS.getCode(), PayExceptionCode.SUCCESS.getDesc());
			}
			break;
		// 划拨
		case TRANSFER_MERCHANT_USER:
			if (!FuiouDepositRspCodeEnum.SUCCESS.getValue().equals(req.getResp_code())) {
				updateItem = transferMerchantUserDao.updateStateRspByBusiId(FuiouDepositStateEnum.FAIL.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), codeExp.getCode(), codeExp.getDesc());
			} else {
				updateItem = transferMerchantUserDao.updateStateRspByBusiId(FuiouDepositStateEnum.SUCCESS.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), PayExceptionCode.SUCCESS.getCode(), PayExceptionCode.SUCCESS.getDesc());
			}
			break;
		// 转账
		case TRANSFER_USER_USER:
			if (!FuiouDepositRspCodeEnum.SUCCESS.getValue().equals(req.getResp_code())) {
				updateItem = transferUserUserDao.updateStateRspByBusiId(FuiouDepositStateEnum.FAIL.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), codeExp.getCode(), codeExp.getDesc());
			} else {
				updateItem = transferUserUserDao.updateStateRspByBusiId(FuiouDepositStateEnum.SUCCESS.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), PayExceptionCode.SUCCESS.getCode(), PayExceptionCode.SUCCESS.getDesc());
			}
			break;
		default:
			logger.warn(Log.op(op).msg("【富友存管-交易通知】业务类型错误！").kv("busiId", req.getMchnt_txn_ssn()).toString());
			break;
		}
		// 没有更新到打印告警日志（两种可能，1：通知的订单id不存在，2：状态不对，这种情况可以忽略）
		if (updateItem <= 0) {
			logger.warn(Log.op(op).msg("【富友存管-交易通知】更新订单状态未命中！").kv("busiId", req.getMchnt_txn_ssn()).toString());
		}

		// 封装异步响应
		BasePlainXMLRsp plain = new BasePlainXMLRsp();
		plain.setRspCode(FuiouDepositRspCodeEnum.SUCCESS.getValue());
		plain.setMerchantCode(req.getMchnt_cd());
		plain.setBusiId(req.getMchnt_txn_ssn());

		ResultXMLRsp rsp = new ResultXMLRsp();
		rsp.setPlain(plain);
		rsp.setSign(fuiouSignService.sign(idVO.getMerchantCode(), plain.toXml()));
		logger.info(Log.op(op).kv("rspParams", rsp.toXml()).msg("【富友存管-交易通知】响应参数！").toString());
		return rsp.toXml();
	}

	@Override
	public String handleEntrustWithdraw(EntrustTradeNotifyReq req) {
		final String op = "TradeNotifyServiceImpl.handleEntrustWithdraw";
		logger.info(Log.op(op).msg("【富友存管】收到委托提现后台通知").kv("req", req).toString());

		if (null == req || StringUtils.isBlank(req.getMchnt_txn_ssn())) {
			logger.warn(Log.op(op).msg("【富友存管】委托提现通知参数异常,直接返回").kv("req", req).toString());
			return "";
		}

		PayBusiIdVO idVO = fuiouIdUtils.parserBusiId(req.getMchnt_txn_ssn());

		boolean verify = fuiouDepositService.checkSignRspResult(idVO.getMerchantCode(), req, req.getSignature());
		if (!verify) {
			logger.error(Log.op(op).msg("存管通知请求参数验签错误!").kv("req", req).toString());
			throw PayExceptionCode.ERROR_SIGN_FAIL.exp();
		}

		FuiouWithdraw po = fuiouWithdrawDao.selectByPrimaryKey(req.getMchnt_txn_ssn());
		if (po == null) {
			logger.error(Log.op(op).msg("【富友存管】委托提现订单不存在").kv("busiId", req.getMchnt_txn_ssn()).toString());
			ResultXMLRsp rsp = getSuccessXMLRsp(req.getMchnt_cd(), req.getMchnt_txn_ssn(), idVO.getMerchantCode());
			return rsp.toXml();
		}

		PayRspCodeVO expCode = fuiouDepositService.converToPayRspCode(req.getResp_code());

		if (FuiouDepositStateEnum.ACCEPTED.isValue(po.getState()) || FuiouDepositStateEnum.DEALING.isValue(po.getState())) {
			if (!FuiouDepositRspCodeEnum.SUCCESS.isValue(req.getResp_code())) {
				logger.warn(Log.op(op).msg("【富友存管】委托提现异步通知失败").kv("响应码", req.getResp_code()).toString());
				fuiouWithdrawDao.updateStateAndRspByBusiId(FuiouDepositStateEnum.FAIL.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), expCode.getCode(), expCode.getDesc());
			} else {
				logger.info(Log.op(op).msg("【富友存管】委托提现异步通知成功").toString());
				fuiouWithdrawDao.updateStateAndRspByBusiId(FuiouDepositStateEnum.SUCCESS.getValue(), req.getMchnt_txn_ssn(),
						DateUtil.getCurrentDateTime(), PayExceptionCode.SUCCESS.getCode(), "交易通知成功");
			}
		} else {
			logger.info(Log.op(op).msg("【富友存管】委托提现订单的状态不是已受理或处理中，不作处理").kv("busiId", req.getMchnt_txn_ssn()).toString());
		}

		// 异步通知业务
		generateNotifyTask(expCode, po.getMerchantCode(), po.getOrderId(), po.getBusiId(), po.getType(), po.getBackUrl());

		// 响应富友
		ResultXMLRsp rsp = getSuccessXMLRsp(req.getMchnt_cd(), req.getMchnt_txn_ssn(), idVO.getMerchantCode());
		return rsp.toXml();
	}

	@Override
	public String handleEntrusCharge(EntrustTradeNotifyReq req) {
		final String op = "TradeNotifyServiceImpl.handleEntrusCharge";
		logger.info(Log.op(op).msg("【富友存管】收到委托充值后台通知").kv("req", req).toString());

		if (null == req || StringUtils.isBlank(req.getMchnt_txn_ssn())) {
			logger.warn(Log.op(op).msg("【富友存管】委托充值通知参数异常,直接返回").kv("req", req).toString());
			return "";
		}

		PayBusiIdVO idVO = fuiouIdUtils.parserBusiId(req.getMchnt_txn_ssn());

		boolean verify = fuiouDepositService.checkSignRspResult(idVO.getMerchantCode(), req, req.getSignature());
		if (!verify) {
			logger.error(Log.op(op).msg("存管通知请求参数验签错误!").kv("req", req).toString());
			throw PayExceptionCode.ERROR_SIGN_FAIL.exp();
		}

		FuiouCharge po = fuiouChargeDao.selectByBusiId(req.getMchnt_txn_ssn());
		if (po == null) {
			logger.error(Log.op(op).msg("【富友存管】委托充值订单不存在").kv("busiId", req.getMchnt_txn_ssn()).toString());
			ResultXMLRsp rsp = getSuccessXMLRsp(req.getMchnt_cd(), req.getMchnt_txn_ssn(), idVO.getMerchantCode());
			return rsp.toXml();
		}
		PayRspCodeVO expCode = fuiouDepositService.converToPayRspCode(req.getResp_code());

		// 委托充值，异步通知交易结果不稳定，会出现多次请求，且结果不一致，只做预警，add by buyi since 2.2.1
		if ((FuiouDepositStateEnum.FAIL.isValue(po.getState()) && FuiouDepositRspCodeEnum.SUCCESS.isValue(req.getResp_code()))
				|| (FuiouDepositStateEnum.SUCCESS.isValue(po.getState()) && !FuiouDepositRspCodeEnum.SUCCESS.isValue(req.getResp_code()))) {
			// 如果订单交易结果是失败，但是异步通知是成功，则预警；
			// 如果订单交易结果是成功，但是异步通知是失败，则预警
			logger.error(Log.op(op).msg("【富友存管】委托提现异步通知警告，订单状态出现不一致").kv("busiId", po.getBusiId()).kv("state", po.getState())
					.kv("富友响应码", req.getResp_code()).toString());
			String expMessage = "";
			if (FuiouDepositStateEnum.FAIL.isValue(po.getState())) {
				expMessage = "【富友委托充值异步通知】支付订单状态为失败,富友异步通知为成功";
			} else {
				expMessage = "【富友委托充值异步通知】支付订单状态为成功,富友异步通知为失败";
			}
			ExceptionRecordDO exceptionRecordDO = buildExceptionRecord(po, expCode.getCode(), expCode.getDesc(), expMessage);

			try {
				entrustChargeExpHandler.saveExceptionRecord(exceptionRecordDO);
			} catch (PayException e) {
				logger.error(Log.op(op).msg("委托充值多次通知异常,保存异常记录失败").kv("exceptionRecordDO", exceptionRecordDO).toString());
			}
		}

		if (FuiouDepositStateEnum.ACCEPTED.isValue(po.getState()) || FuiouDepositStateEnum.DEALING.isValue(po.getState())) {
			if (!FuiouDepositRspCodeEnum.SUCCESS.isValue(req.getResp_code())) {
				logger.warn(Log.op(op).msg("【富友存管】委托充值异步通知失败").kv("响应码", req.getResp_code()).toString());
				fuiouChargeDao.updateState(po.getBusiId(), FuiouDepositStateEnum.FAIL.getValue(), FuiouDepositStateEnum.ACCEPTED.getValue(),
						expCode.getCode(), expCode.getDesc(), DateUtil.getCurrentDateTime());
			} else {
				logger.info(Log.op(op).msg("【富友存管】委托充值异步通知成功").toString());
				fuiouChargeDao.updateState(po.getBusiId(), FuiouDepositStateEnum.SUCCESS.getValue(), FuiouDepositStateEnum.ACCEPTED.getValue(),
						PayExceptionCode.SUCCESS.getCode(), "交易通知成功", DateUtil.getCurrentDateTime());
			}
		} else {
			logger.info(Log.op(op).msg("【富友存管】委托充值订单的状态不是已受理或处理中，不作处理").kv("busiId", req.getMchnt_txn_ssn()).toString());
		}

		// 异步通知业务
		generateNotifyTask(expCode, po.getMerchantCode(), po.getOrderId(), po.getBusiId(), po.getType(), po.getBackUrl());

		// 响应富友
		ResultXMLRsp rsp = getSuccessXMLRsp(req.getMchnt_cd(), req.getMchnt_txn_ssn(), idVO.getMerchantCode());
		return rsp.toXml();
	}

	/**
	 * 构建异常记录
	 *
	 * @param po, code, desc
	 * @return com.yyfax.pay.console.domain.ExceptionRecordDO
	 * @throws Exception
	 * @author wangjwy
	 * @date 2018/6/27 14:46
	 * @since 2.2.3
	 */
	private ExceptionRecordDO buildExceptionRecord(FuiouCharge po, int code, String desc, String expMessage) {
		ExceptionRecordDO exceptionRecordDO = new ExceptionRecordDO();
		exceptionRecordDO.setBusiId(po.getBusiId());
		exceptionRecordDO.setOrderTime(po.getOrderTime());
		exceptionRecordDO.setExpCode(code + "");
		exceptionRecordDO.setExpDesc(desc);
		exceptionRecordDO.setExpMessage(expMessage);
		exceptionRecordDO.setOrderInfo(JacksonUtil.toJson(po));
		exceptionRecordDO.setState(ExpRecordStateEnum.NOT_RESOLV.getValue());
		exceptionRecordDO.setBusiType(BusiTypeEnum.ENTRUST_CHARGE.getValue());
		exceptionRecordDO.setBusiName(BusiTypeEnum.ENTRUST_CHARGE.getName());
		exceptionRecordDO.setExceptionType(EntrustChargeExceptionTypeEnum.ENTRUST_NOTIFY_2TIMES.getValue());
		return exceptionRecordDO;
	}

	@Override
	public String handleWithdrawCancel(WithdrawNotifyReq req) {
		final String op = "TradeNotifyServiceImpl.handleWithdrawCancel";
		logger.warn(Log.op(op).msg("【富友存管】收到提现退票通知").kv("req", req).toString());

		// edit by wangjw since 2.1.2
		if (null == req || StringUtils.isBlank(req.getMchnt_txn_ssn())) {
			logger.warn(Log.op(op).msg("【富友存管】退票通知参数异常,直接返回").kv("req", req).toString());
			return "";
		}

		PayBusiIdVO idVO = fuiouIdUtils.parserBusiId(req.getMchnt_txn_ssn());

		boolean verify = fuiouDepositService.checkSignRspResult(idVO.getMerchantCode(), req, req.getSignature());
		if (!verify) {
			logger.error(Log.op(op).msg("存管通知请求参数验签错误!").kv("req", req).toString());
			throw PayExceptionCode.ERROR_SIGN_FAIL.exp();
		}

		FuiouWithdraw po = fuiouWithdrawDao.selectByPrimaryKey(req.getMchnt_txn_ssn());
		if (po == null) {
			logger.error(Log.op(op).msg("【富友存管】提现订单不存在").kv("busiId", req.getMchnt_txn_ssn()).toString());
			return "SUCCESS";
		}

		// 把退票的订单改为失败
		PayExceptionCode payExceptionCode = PayExceptionCode.WITHDRAW_CANCEL;
		fuiouWithdrawDao.updateStateAndRspByBusiId(FuiouDepositStateEnum.FAIL.getValue(), req.getMchnt_txn_ssn(), DateUtil.getCurrentDateTime(),
				payExceptionCode.getCode(), payExceptionCode.getDesc());
		logger.warn(Log.op(op).msg("【富友存管】发生提现退票").kv("busiId", req.getMchnt_txn_ssn()).kv("orderId", po.getOrderId()).toString());

		// 异步通知业务
		PayRspCodeVO expCode = PayRspCodeVO.newInstance(payExceptionCode);
		generateNotifyTask(expCode, po.getMerchantCode(), po.getOrderId(), po.getBusiId(), FuiouBusiTypeEnum.WITHDRAW_CANCEL.getValue(),
				po.getNotifyUrl());

		return "SUCCESS";
	}

	private void generateNotifyTask(PayRspCodeVO code, String merchantCode, String orderId, String busiId, String type, String backUrl) {
		try {
			RspParamsVO params = new RspParamsVO();
			params.setOrderId(orderId);
			params.setRspCode(code.getCode());
			params.setRspMsg(code.getDesc());
			params.setBusiId(busiId);

			YYPayApiReq2<RspParamsVO> req = new YYPayApiReq2<>();
			req.setMerchantCode(merchantCode);
			req.setSign(payCommonService.getSign(merchantCode, params));
			req.setParams(params);

			fuiouDepositCommonService.saveNotifyTask(merchantCode, orderId, busiId, FuiouBusiTypeEnum.parse(type), backUrl, FastJsonUtil.toJson(req),
					null, null);
		} catch (Exception e) {
			logger.error(Log.op("TradeNotifyServiceImpl.generateChargeNotifyTask").msg("封装同步结果异步通知任务异常").kv("orderId", orderId).kv("busiId", busiId)
					.kv("merchantCode", merchantCode).toString(), e);
		}
	}

	private ResultXMLRsp getSuccessXMLRsp(String merchantId, String busiId, String merchantCode) {
		BasePlainXMLRsp plain = new BasePlainXMLRsp();
		plain.setRspCode(FuiouDepositRspCodeEnum.SUCCESS.getValue());
		plain.setMerchantCode(merchantId);
		plain.setBusiId(busiId);

		ResultXMLRsp rsp = new ResultXMLRsp();
		rsp.setPlain(plain);
		rsp.setSign(fuiouSignService.sign(merchantCode, plain.toXml()));
		return rsp;
	}

}
